package org.shs.waste.service;

import static org.shs.common.config.SystemInitializer.app_msgs;

import java.util.ArrayList;

import org.apache.log4j.Logger;
import org.shs.common.dao.CommonDAOFactory;
import org.shs.user.service.UserService;
import org.shs.waste.dao.IWasteDAO;
import org.shs.waste.form.WasteTypeForm;
import org.shs.waste.model.WasteTypeModel;

/**
 * This class serves separates all the business logic from the presentation
 * layer for the waste module
 * <br/>
 * <br/><b>Created:</b>&nbsp;&nbsp; 19-Nov-2008 23:56:38
 *
 * @author anirvan
 *
 */
public class WasteService
{
   /**
    * The reference for the DAO interface associated with this 
    * service class.
    */
   private IWasteDAO wasteDao = null;
   
   /**
    * The logger instance to be used
    */
   private static Logger logger = Logger.getLogger(UserService.class);
   
   /**
    * The default constructor
    */
   public WasteService()
   {
      try
      {
         //Initialize the DAO instance
         wasteDao = (IWasteDAO)CommonDAOFactory
                        .getDAO(app_msgs.getMessage("waste.daoImpl"));
      }
      catch (Exception e) 
      {
         logger.error("[Possible cause] No key present for {waste.daoImpl}.", e);
      }
   }
   
   /**
    * Retrieves the list of waste types. Used for general retrieval as well as
    * a search scenario
    * @param wasteTypeDesc the description of the waste type to be searched
    * @return the list of waste types
    */
   public ArrayList<WasteTypeModel> getWasteTypes(String wasteTypeDesc)
   {
      ArrayList<WasteTypeModel> wasteTypes = null;
      
      try
      {
         // This is going to be a wild-card contains query
         wasteTypeDesc = (wasteTypeDesc == null) ? "%%"
                         : "%" + wasteTypeDesc + "%";
         // Fetch the list
         wasteTypes = wasteDao.getWasteTypes(wasteTypeDesc);
      }
      catch (Exception e)
      {
         logger.error(String.format("Could not retrieve the list of waste " +
         		                     "types for [%s]", wasteTypeDesc), e);
      }
      
      return wasteTypes;
   }
   
   /**
    * Retrieves the details for a particular waste type
    * @param wasteTypeId The ID of the waste type
    * @return The model encapsulating all details about the waste type
    * @throws Exception if query resulted in an error.
    */
   public WasteTypeModel getWasteTypeDetails(String wasteTypeId)
   {
      WasteTypeModel wasteType = null;
      
      try
      {
         // Fetch the details
         wasteType = wasteDao.getWasteTypeDetails(wasteTypeId);
      }
      catch (Exception e)
      {
         logger.error(String.format("Could not retrieve the waste details " +
                                    " for ID [%s]", wasteTypeId), e);
      }
      
      return wasteType;
   }
   
   /**
    * Retrieves the list of aggregate waste types. 
    * @return the list of aggregate waste types
    */
   public ArrayList<WasteTypeModel> getAggrWasteTypes()
   {
      ArrayList<WasteTypeModel> aggrWasteTypes = null;
      
      try
      {
         // Fetch the list of aggregate waste types
         aggrWasteTypes = wasteDao.getAggrWasteTypes();
      }
      catch (Exception e)
      {
         logger.error("Could not retrieve the list of aggregate waste types.", 
                      e);
      }
      
      return aggrWasteTypes;
   }
   
   /**
    * Adds the details for a new waste type
    * @param wasteTypeData The data about the new waste type
    * @return the details about the added waste type
    */
   public WasteTypeModel addWasteTypeDetails(WasteTypeForm wasteTypeData)
   {
      String wasteTypeId = null;
      WasteTypeModel savedWasteTypeData = null;
      
      try
      {
         // Add the waste type data
         wasteTypeId = wasteDao.addWasteTypeData(wasteTypeData);
         if (wasteTypeId != null)
         {
            wasteTypeData.setWasteTypeId(wasteTypeId);
            // Insert a record in the history table as well.
            addWasteTypeHistDetails(wasteTypeData);
         }
         
         // Retrieve the waste type details to display on the screen
         savedWasteTypeData = wasteDao.getWasteTypeDetails(wasteTypeId);
      }
      catch (Exception e)
      {
         logger.error("Could not save the waste type data.", e);
      }
      
      return savedWasteTypeData;
   }
   
   /**
    * Updates the details for an existing waste type
    * @param wasteTypeData The data about the waste type
    * @return the updated waste type details
    */
   public WasteTypeModel editWasteTypeDetails(WasteTypeForm wasteTypeData)
   {
      WasteTypeModel savedWasteTypeData = null;
      
      try
      {
         // Add the waste type data
         wasteDao.editWasteTypeData(wasteTypeData);
         if (!wasteTypeData.getOrigMrktRate().equals(
                  wasteTypeData.getAvgMrktRate().trim()))
         {
            // Add a history record to track the change in price
            addWasteTypeHistDetails(wasteTypeData);
         }
         
         // Retrieve the waste type details to display on the screen
         savedWasteTypeData = wasteDao.getWasteTypeDetails(
                                          wasteTypeData.getWasteTypeId());
      }
      catch (Exception e)
      {
         logger.error(String.format("Could not update the waste type data - " +
                                    "[{%s} - %s].", 
                                    wasteTypeData.getWasteTypeId(),
                                    wasteTypeData.getWasteTypeDesc()), 
                      e);
      }
      
      return savedWasteTypeData;
   }
   
   /**
    * Adds the details for a new waste type into the history table
    * @param wasteTypeData The data about the waste type
    */
   public void addWasteTypeHistDetails(WasteTypeForm wasteTypeData)
   {
      try
      {
         // Add the waste type data
         wasteDao.addWasteTypeHistData(wasteTypeData);
      }
      catch (Exception e)
      {
         logger.error(String.format("Could not save the waste type data - " +
                                    "[{%s} - %s] - into the history table.", 
                                    wasteTypeData.getWasteTypeId(),
                                    wasteTypeData.getWasteTypeDesc()),
                      e);
      }
   }
   
   /**
    * Deletes the details for a waste type
    * @param wasteTypeData The data about the waste types
    * @return the status of all delete operations
    */
   public boolean delWasteTypeDetails(WasteTypeForm wasteTypeData)
   {
      String[] wasteTypeIds = wasteTypeData.getChkWasteTypeId();
      boolean status = false;
      
      try
      {
         // Retrieve all checked waste types
         for (String wasteTypeId : wasteTypeIds)
         {
            wasteDao.delWasteTypeData(wasteTypeId);
         }
         status = true;
      }
      catch (Exception e)
      {
         logger.error(String.format("Could not delete the waste type data - " +
                                    "[{%s} - %s].", 
                                    wasteTypeData.getWasteTypeId(),
                                    wasteTypeData.getWasteTypeDesc()),
                      e);
      }
      
      return status;
   }
   
   
}
